﻿using Infrastructure;
using ZR.Model;
using ZR.Model.Souvenir;
using ZR.Model.Souvenir.Dto;
using ZR.Service.Souvenir.IService;
using ZR.ServiceCore.Model;
using ZR.ServiceCore.Services.IService;

namespace ZR.Service.Souvenir
{
    [AppService(ServiceType = typeof(IProductService), ServiceLifetime = LifeTime.Transient)]
    public class ProductService : BaseService<Product>, IProductService
    {
        private readonly ISysFileService _sysFileService;

        public ProductService(ISysFileService sysFileService)
        {
            _sysFileService = sysFileService;
        }

        public async Task<int> InsertProductAsync(Product product)
        {
            return await Insertable(product).ExecuteCommandAsync();
        }

        public async Task<int> UpdateProductAsync(Product product)
        {
            return await Updateable(product).ExecuteCommandAsync();
        }

        public async Task<int> DeleteProductAsync(int productId)
        {
            var product = await SelectProductAsyncById(productId);
            if (product == null) throw new CustomException("要删除的纪念品不存在");
            try
            {
                await Context.Ado.BeginTranAsync();
                var res = await Deleteable()
                    .Where(it => it.Id == productId)
                    .ExecuteCommandAsync();
                await _sysFileService.DeleteSysFileAsync(new[] { product.ImageId });
                await Context.Ado.CommitTranAsync();
                return res;
            }
            catch (Exception e)
            {
                await Context.Ado.RollbackTranAsync();
                throw;
            }
            
        }

        public async Task<PagedInfo<ProductDto>> SelectProductWithPageAsync(ProductQueryDto productQueryDto)
        {
            RefAsync<int> total = 0;
            var exp = Expressionable.Create<Product>();
            exp.AndIF(productQueryDto.CategoryId != 0, p => p.CategoryId == productQueryDto.CategoryId);
            var res = await Queryable()
                .LeftJoin<SysFile>((p, f) => p.ImageId == f.Id)
                .LeftJoin<Category>((p, f, c) => p.CategoryId == c.Id)
                .Where(exp.ToExpression())
                .Select((p, f, c) => new ProductDto()
                {
                    Id = p.Id,
                    Name = p.Name,
                    ImageId = p.ImageId,
                    ImageUrl = f.AccessUrl,
                    Price = p.Price,
                    Stock = p.Stock,
                    Detail = p.Detail,
                    Status = p.Status,
                    CategoryId = p.CategoryId,
                    CategoryName = c.Name
                })
                .ToPageListAsync(productQueryDto.PageNum, productQueryDto.PageSize, total);
            var page = new PagedInfo<ProductDto>()
            {
                PageIndex = productQueryDto.PageNum,
                PageSize = productQueryDto.PageSize,
                Result = res,
                TotalNum = total
            };
            return page;
        }

        public async Task<Product> SelectProductAsyncById(int productId)
        {
            return await Queryable()
                .Where(it => it.Id == productId)
                .FirstAsync();
        }
    }
}